using System;
using System.Collections;
using System.Collections.Generic;


namespace LightCAD.Three
{
    public class HemisphereLightHelper : Object3D
    {
        #region scope properties or methods
        //private static Vector3 _vector = new Vector3();
        //private static Color _color1 = new Color();
        //private static Color _color2 = new Color();
        public HemisphereLightHelperContext getContext()
        {
            return ThreeThreadContext.GetCurrThreadContext().HemisphereLightHelperCtx;
        }
        #endregion

        #region Properties

        public HemisphereLight light;
        public Color color;
        public MeshBasicMaterial material;

        #endregion

        #region constructor
        public HemisphereLightHelper(HemisphereLight light, double size, Color color = null)
        {
            this.light = light;
            this.matrix = light.matrixWorld;
            this.matrixAutoUpdate = false;
            this.color = color;
            this.type = "HemisphereLightHelper";
            var geometry = new OctahedronGeometry(size);
            geometry.rotateY(MathEx.PI * 0.5);
            this.material = new MeshBasicMaterial{ wireframe = true, fog = false, toneMapped = false };
            if (this.color == null) this.material.vertexColors = true;
            var position = geometry.getAttribute("position");
            var colors = new double[position.count * 3];
            geometry.setAttribute("color", new BufferAttribute(colors, 3));
            this.add(new Mesh(geometry, this.material));
            this.update();
        }
        #endregion

        #region methods
        public void dispose()
        {
            (this.children[0] as Mesh).geometry.dispose();
            (this.children[0] as Mesh).material.dispose();
        }
        public void update()
        {
            var ctx = getContext();
            var _vector = ctx._vector;
            var mesh = this.children[0] as Mesh;
            if (this.color != null)
            {
                this.material.color.Set(this.color);
            }
            else
            {
                var _color1 = ctx._color1;
                var _color2 = ctx._color2;
                var colors = mesh.geometry.getAttribute("color");
                _color1.Copy(this.light.color);
                _color2.Copy(this.light.groundColor);
                for (int i = 0, l = colors.count; i < l; i++)
                {
                    var color = (i < (l / 2)) ? _color1 : _color2;
                    colors.setXYZ(i, color.R, color.G, color.B);
                }
                colors.needsUpdate = true;
            }
            this.light.updateWorldMatrix(true, false);
            mesh.lookAt(_vector.SetFromMatrixPosition(this.light.matrixWorld).Negate());
        }
        #endregion

    }
}
